package com.example.cadmin.controller;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.cadmin.ExcelDao.EmployeesListener;
import com.example.cadmin.entity.*;
import com.example.cadmin.entityVo.TableVo;
import com.example.cadmin.mapper.ElectronArchivesMapper;
import com.example.cadmin.mapper.SysParamsetMapper;
import com.example.cadmin.security.dto.JwtUserDto;
import com.example.cadmin.service.*;
import com.example.cadmin.utils.DateFormat;
import com.example.cadmin.utils.RFIDMAP;
import com.example.cadmin.utils.ResponseModel;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;


/**
 * <p>
 * 智能选层柜 档案管理-控制器
 * </p>
 *
 * @author 张彬
 * @since 2022-08-20
 */
@Controller
@RequestMapping("/file/manage")
@Slf4j
public class FileManageController {
    @Autowired
    private FileManageService fileManageService;
    @Autowired
    private ArchivesService archivesService;
    @Autowired
    private MyUserService myUserService;
    @Autowired
    private HostService hostService;
    @Autowired
    public com.example.cadmin.utils.Netty.sendCmd sendCmd;

    @javax.annotation.Resource
    public SysParamsetMapper sysParamsetMapper;
    @javax.annotation.Resource
    public ElectronArchivesMapper electronArchivesMapper;

    @Value("${SavePath.nginxPath}")
    private String nginxPath;

    /**
     * 封装层和列循环
     */
    public Map<String, Object> layerColumnFor(HttpServletRequest request) {
        String number = Convert.toStr(request.getSession().getAttribute("number"));
        Host host = hostService.getOne(new QueryWrapper<Host>().eq("number", number));
        List<Object> layerList = new ArrayList<>();
        for (int layer = 1; layer <= Convert.toInt(host.getNumberOfLayers()); layer++) {
            layerList.add(layer);
        }
        List<Object> columnList = new ArrayList<>();
        for (int column = 1; column <= Convert.toInt(host.getNumberOfColumns()); column++) {
            columnList.add(column);
        }
        Map<String, Object> layerColumn = new HashMap<>();
        layerColumn.put("layerList", layerList);
        layerColumn.put("columnList", columnList);
        return layerColumn;
    }

    /**
     * 档案列表
     */
    @GetMapping("index")
    public ModelAndView checkBorrowIndex(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addAllObjects(layerColumnFor(request));
        modelAndView.setViewName("FileManage/list");
        modelAndView.addObject("userList", myUserService.list());
        List<Map<String, Object>> hostList = hostService.listMaps();
        modelAndView.addObject("hostList", hostList);
        List<Map<String, Object>> mapList = archivesService.listMaps(new QueryWrapper<Archives>().groupBy("year").select("year"));
        List<String> yearList = new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            yearList.add(Convert.toStr(map.get("year")));
        }
        yearList.sort(Comparator.naturalOrder());
        modelAndView.addObject("yearList", yearList);
        return modelAndView;
    }

    /**
     * list接口
     *
     * @param page     页面
     * @param limit    分页条数
     * @param fileName 搜索文件名称
     * @return
     * @throws IOException
     */
    @GetMapping("list")
    @ResponseBody
    public Map<String, Object> checkBorrowList(@RequestParam(value = "page") int page,
                                               @RequestParam(value = "limit") int limit,
                                               @RequestParam(value = "reference", required = false) String reference,
                                               @RequestParam(value = "fileName", required = false) String fileName,
                                               @RequestParam(value = "fileNo", required = false) String fileNo,
                                               @RequestParam(value = "year", required = false) String year,
                                               @RequestParam(value = "userId", required = false) String userId,
                                               @RequestParam(value = "number", required = false) String number,
                                               @RequestParam(value = "layer", required = false) String layer,
                                               @RequestParam(value = "column", required = false) String column,
                                               @RequestParam(value = "startDate", required = false) String startDate,
                                               @RequestParam(value = "endDate", required = false) String endDate) {
        return fileManageService.checkBorrowList(page, limit, fileName, number, layer, column, userId, startDate, endDate, year, reference, fileNo);
    }

    /**
     * 取出档案视图
     */
    @GetMapping("takeout/view")
    @PreAuthorize("hasAnyAuthority('file:takeout')")
    public ModelAndView takeoutView(@RequestParam(value = "fileId") String fileId) {
        return fileManageService.takeoutView(fileId);
    }


    /**
     * 取出档案保存
     */
    @PostMapping("takeout/save")
    @ResponseBody
    @PreAuthorize("hasAnyAuthority('file:takeout')")
    public ResponseModel takeOutSave(@RequestBody JSONObject data, HttpServletRequest request) throws InterruptedException {
        return fileManageService.takeOutSave(data, request);
    }

    /**
     * 归还档案页面
     */
    @GetMapping("returnFile")
    @PreAuthorize("hasAnyAuthority('file:return')")
    public ModelAndView takeOut(@RequestParam(value = "uuid") String uuid) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("FileManage/returnFile");
        List<Archives> archivesList = archivesService.list(new QueryWrapper<Archives>().eq("uuid",uuid));
        modelAndView.addObject("fileName", archivesList.get(0).getFileName());
        modelAndView.addObject("uuid", archivesList.get(0).getUuid());
        return modelAndView;
    }

    /**
     * 归还档案
     */
    @PostMapping("returnFile")
    @ResponseBody
    @PreAuthorize("hasAnyAuthority('file:return')")
    public ResponseModel returnFile(@RequestBody JSONObject data, HttpServletRequest request) throws IOException, InterruptedException {
        return fileManageService.returnFile(data, request);
    }

    /**
     * 档案录入界面
     */
    @GetMapping("insert")
    @PreAuthorize("hasAnyAuthority('file:add')")
    public ModelAndView insert(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String sendIpAddress = Convert.toStr(session.getAttribute("cabinet"));
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("FileManage/add");
        // 获取用户信息
        JwtUserDto jwtUserDto = (JwtUserDto) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userName = jwtUserDto.getMyUser().getUserName();
        modelAndView.addObject("userName", userName);
        List<MyUser> myUserList = myUserService.list();
        modelAndView.addObject("myUserList", myUserList);
        return modelAndView;
    }

    /**
     * 档案录入保存接口
     */
    @PostMapping("save")
    @ResponseBody
    @PreAuthorize("hasAnyAuthority('file:add')")
    public ResponseModel save(@RequestBody JSONObject data, HttpServletRequest request) throws IOException {
        if (StrUtil.isEmpty(data.getStr("fileName"))) {
            return ResponseModel.fail("缺少参数");
        }
        return fileManageService.save(data, request);
    }

    //删除档案
    @DeleteMapping("/delete/{id}")
    @ResponseBody
    @ApiOperation("删除档案")
    @PreAuthorize("hasAnyAuthority('file:del')")
    public ResponseModel delete(@PathVariable("id") String id) throws IOException {
        return fileManageService.delete(id);
    }

    /**
     * 下载批量入库模版
     */
    @GetMapping("/download/template")
    public void downloadTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String filePath = "static/excel/批量录入.xlsx";
        // 重要! 设置返回格式是excel形式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 设置编码格式
        response.setCharacterEncoding("utf-8");
        // 设置URLEncoder.encode 防止中文乱码
        String fileName = null;
        fileName = URLEncoder.encode("档案批量录入模版", "UTF-8").replaceAll("\\+", "%20");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 模板文件保存在springboot项目的resources/static下
        Resource resource = new ClassPathResource(filePath);
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                .withTemplate(resource.getInputStream()) // 利用模板的输出流
                .build();
        excelWriter.finish();
    }

    /**
     * EasyExcel 批量入库
     */
    @PostMapping("/upload/")
    @ResponseBody
//    @PreAuthorize("hasAnyAuthority('file:add')")
    public ResponseModel upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
        InputStream inputStream = file.getInputStream();
        EasyExcel.read(inputStream, TableVo.class, new EmployeesListener()).sheet().doRead();
        return ResponseModel.success("上传成功");
    }

    /**
     * 修改档案
     */
    @GetMapping("edit")
    @PreAuthorize("hasAnyAuthority('file:edit')")
    public ModelAndView editView(@RequestParam(value = "id") String id)  {
        return fileManageService.editView(id);
    }

    /**
     * 修改档案
     */
    @PostMapping("edit/save")
    @ResponseBody
    public ResponseModel editSave(@RequestBody JSONObject data) {
        return fileManageService.editSave(data);

    }

    /**
     * 上传电子档案文件
     */
    @PostMapping("/upload/electron/file")
    @ResponseBody
    public Map<String, Object> uploadImg(@RequestPart("file") MultipartFile file, @RequestParam(value = "archivesId", required = false) String archivesId) {
        Map<String, Object> resMap = new HashMap<>();
        //获取文件名
        String fileName = file.getOriginalFilename();
        //获取文件后缀名。也可以在这里添加判断语句，规定特定格式的图片才能上传，否则拒绝保存。
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //为了避免发生图片替换，这里使用了文件名重新生成
        fileName = UUID.randomUUID() + suffixName;
        //拼接前缀路径
        LocalDateTime localDateTime = LocalDateTime.now();
        String middlePath = localDateTime.getYear() + File.separator + localDateTime.getMonthValue();
        SysParamset sysParamset = sysParamsetMapper.selectById(1);
        String basePathJoin = sysParamset.getParamValue() + File.separator + middlePath;
        log.info("basePathJoin: " + basePathJoin);
        if (!FileUtil.exist(basePathJoin)) {
            File file1 = FileUtil.mkdir(basePathJoin);
            log.info("创建文件夹成功：" + file1.getAbsolutePath());
        }
        try {
            File savePath = new File(basePathJoin + File.separator + fileName);
            //将图片保存到文件夹里
            file.transferTo(savePath);
            //返回文件的路径
            String nginx = nginxPath + middlePath + File.separator + fileName;
            resMap.put("data", nginx);
            resMap.put("msgName", "图片保存成功");
            resMap.put("code", 0);
            // 读取PDF
//            PDDocument document = PDDocument.load(savePath);
//            // 创建PDFTextStripper对象
//            PDFTextStripper pdfStripper = new PDFTextStripper();
//            // 提取文本
//            String text = pdfStripper.getText(document);
//            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
//            Matcher m = p.matcher(text);
//            String str1 = m.replaceAll("");
//            //只关注这些词性的词
//            Set<String> name = new HashSet<String>() {{
//                add("n");
//                add("nr");
//                add("nr1");
//                add("nr2");
//                add("nrj");
//                add("nrf");
//            }};
//            Set<String> placeName = new HashSet<String>() {{
//                add("ns");
//                add("nsf");
//                add("nt");
//                add("nz");
//                add("f");
//            }};
//            Set<String> number = new HashSet<String>() {{
//                add("m");
//            }};
//            Set<String> time = new HashSet<String>() {{
//                add("t");
//            }};
//            Result result = ToAnalysis.parse(str1);
//            List<Term> terms = result.getTerms(); //拿到terms
//            HashSet<String> documentName = new HashSet<>();
//            HashSet<String> documentPlaceName = new HashSet<>();
//            HashSet<String> documentNumber = new HashSet<>();
//            HashSet<String> documentTime = new HashSet<>();
//            for (int i = 0; i < terms.size(); i++) {
//                String word = terms.get(i).getName(); //拿到词
//                String natureStr = terms.get(i).getNatureStr(); //拿到词性
//                if (name.contains(natureStr)) {
//                    documentName.add(word);
//                } else if (placeName.contains(natureStr)) {
//                    documentPlaceName.add(word);
//                } else if (number.contains(natureStr)) {
//                    documentNumber.add(word);
//                } else if (time.contains(natureStr)) {
//                    documentTime.add(word);
//                }
//            }
            if (StrUtil.isNotEmpty(archivesId)) {
                ElectronArchives electronArchives = new ElectronArchives();
                electronArchives.setArchivesId(Convert.toInt(archivesId));
                electronArchives.setElectronFile(nginx);
//                electronArchives.setDocumentName(documentName.toString());
//                electronArchives.setDocumentPlacename(documentPlaceName.toString());
//                electronArchives.setDocumentNumber(documentNumber.toString());
//                electronArchives.setDocumentTime(documentTime.toString());
                electronArchives.setCreateTime(DateFormat.getTime());
                electronArchives.setUploadFileName(file.getOriginalFilename());
                electronArchives.setSavePath(savePath.getAbsolutePath());
                electronArchives.setUpdateTime(DateFormat.getTime());
                electronArchivesMapper.insert(electronArchives);

                archivesService.update(new UpdateWrapper<Archives>().eq("id", Convert.toInt(archivesId)).set("electron_file",1));
            }
            return resMap;
        } catch (Exception e) {
            e.printStackTrace();
            resMap.put("code", 1);
            return resMap;
        }
    }

    /**
     * 打印二维码
     */
    @GetMapping("qrCode")
    public ModelAndView qrCode(@RequestParam(value = "fileName") String fileName) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("qrCode");
        if (fileName.length() > 5) {
            fileName = fileName.substring(0, 5) + "...";
        }
        modelAndView.addObject("fileName", fileName);
        modelAndView.addObject("date", DateFormat.getDate());
        modelAndView.addObject("uuid", IdUtil.simpleUUID());
        return modelAndView;
    }

    /**
     * 上传电子档案（对接高拍仪）
     */
    @GetMapping("/upload/electron")
    public ModelAndView uploadElectronFile(@RequestParam(value = "id") String id) {
        ModelAndView modelAndView = new ModelAndView();
        SysParamset sysParamset = sysParamsetMapper.selectById(31);
        modelAndView.addObject("electronFilePath", sysParamset.getParamValue());
        modelAndView.addObject("archivesId", id);
        modelAndView.setViewName("FileManage/uploadElectronFile");
        return modelAndView;
    }

    /**
     * 电子档案保存
     *
     * @param data
     * @return
     */
    @PostMapping("/electron/save")
    @ResponseBody
    public ResponseModel electronSave(@RequestBody JSONObject data) {
        boolean updateStatus = archivesService.update(new UpdateWrapper<Archives>().eq("id", data.getInt("archivesId"))
                .set("electron_file", data.getStr("uploadElectronPath")));
        return updateStatus ? ResponseModel.success("保存成功") : ResponseModel.fail("保存失败");
    }

    /**
     * 档案新增树结构
     */
    @GetMapping("/position/tree")
    @ResponseBody
    public List<Map<String, Object>> positionTree(HttpServletRequest request) {
        return fileManageService.positionTree(new ArrayList<>(),request);
    }

    /**
     * 档案归还树结构
     */
    @GetMapping("/position/return/tree")
    @ResponseBody
    public List<Map<String, Object>> positionReturnTree(@RequestParam(value = "uuid") String uuid, HttpServletRequest request) {
        List<Archives> archivesList = archivesService.list(new QueryWrapper<Archives>().eq("uuid", uuid));
        List<String> archivesListExists = new ArrayList<>();
        for (Archives archives : archivesList) {
            archivesListExists.add(archives.getCurrentLayer() + "-" + archives.getCurrentColumn());
        }
        return fileManageService.positionTree(archivesListExists,request);
    }
}
